import random
import string

from django.contrib.auth.models import User, Group
from django.shortcuts import render
from rest_framework.viewsets import ModelViewSet, ViewSet
from rest_framework.response import Response
from rest_framework.status import HTTP_404_NOT_FOUND
from school.models import Classes
from school.serializers import ClassesSerializer
from rest_framework.permissions import IsAuthenticated
from user.serializers import CreateUserSerializer
from utils.customPermissions import TeacherPermission
from celery_tasks.email.tasks import send_mail_task


class ClassesViewSet(ModelViewSet):
    queryset = Classes.objects.filter(is_delete=False)
    serializer_class = ClassesSerializer
    # permission_classes = [IsAuthenticated]  # 使用内置校验登录权限，是user还是游客
    permission_classes = [TeacherPermission]  # 使用自定义登录权限


class ClassesMemberViewSet(ViewSet):
    serializer_class = CreateUserSerializer
    permission_classes = [TeacherPermission]  # 老师才有登录权限

    def add_member(self, request, pk):  # pk=班级id
        # 1.获取指定的班级
        try:
            classes = Classes.objects.get(id=pk)
        except Classes.DoesNotExist:
            return Response(status=HTTP_404_NOT_FOUND)

        # 2.判断成员是否属于该班级，如果属于，返回提示‘该成员已加入该班级’，代码终止
        username = request.data['username']
        member = classes.member.filter(username=username)
        if member:
            return Response({'msg': '该成员已加入该班级'})

        # 3.如果不属于，判断该成员是否已经注册，如果已注册，添加班级，代码终止
        user = User.objects.filter(username=username)
        if user:  # 如果该成员已经注册
            Classes.member.add(user[0])  # 因为上面user拿到的是一个查询集，所以这里通过下标取值才能拿到一个对象
            return Response(CreateUserSerializer(user[0]).data)

        # 4.如果没注册，注册用户，生成初始密码
        user_serializer = CreateUserSerializer(data=request.data)
        user_serializer.is_valid(raise_exception=True)  # 数据校验
        first_name = request.data['first_name']
        email = request.data['email']
        user = User(username=username, first_name=first_name, email=email)
        # 生成随机6位初始密码
        source = string.ascii_letters + string.digits  # 52个大小写字母+10个数字
        password = ''.join(random.sample(source, 6))
        user.set_password(password)  # 因为在User表的password字段是密文的，因此要用set_password才能加进表
        user.save()

        # 5.新账户放到学生组并添加班级
        group = Group.objects.get(id=2)  # 拿到学生组
        group.user_set.add(user)  # 模型反向操作，通过user_set管理器把user添加到学生组
        classes.member.add(user)  # 模型正向操作，通过member中间字段把user添加到班级

        # 6.通过邮件发送账户初始密码到该学生邮箱
        # delay方法表示提交一个异步任务到队列中，必须要把send_mail_task变成一个celery的异步任务之后才能调用(加上装饰器@app.task)
        send_mail_task.delay(email, username, password, classes.name)

        return Response(user_serializer.data)
